package cn.com.framework;

import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Properties;

import javax.servlet.ServletContext;

import org.springframework.context.ApplicationContext;
import org.springframework.core.io.Resource;
import org.springframework.util.DefaultPropertiesPersister;
import org.springframework.util.PropertiesPersister;
import org.springframework.web.context.support.ServletContextResource;
import org.springframework.web.servlet.DispatcherServlet;

import cn.com.service.sys.MenuService;
import cn.com.support.context.MenuContext;

/**
 * 继承了Spring-MVC的<code>DispatcherServlet</code>
 * ，添加应用程序配置项功能，在配置文件中的属性可以在servletContext中获取。
 * 
 * @author Microbun 2012-2-10上午2:39:54
 * @version $Id: InitConfigDispatcherServlet.java 2 2012-02-14 07:31:38Z
 *          microbun $
 * @since 1.0
 */

public class InitConfigDispatcherServlet extends DispatcherServlet {

	private static final long serialVersionUID = -8904422965091905599L;

	private final static String DEFAULT_CONFIG_LOCATION = "/WEB-INF/config.properties";

	private static final String XML_FILE_EXTENSION = ".xml";

	private String configLocation = DEFAULT_CONFIG_LOCATION;

	private String configFileEncoding;

	private PropertiesPersister propertiesPersister = new DefaultPropertiesPersister();

	private Properties config;

	@Override
	protected void onRefresh(ApplicationContext context) {
		super.onRefresh(context);
		initApplicationConfig();
		//
		logger.info("init MenuContext ...");
		MenuService menuService = context.getBean(MenuService.class);
		menuService.resetCache();
		logger.info("inited MenuContext ...");
	}

	/**
	 * 初始化配置项
	 */
	private void initApplicationConfig() {
		ServletContext servletContext = getServletContext();
		ServletContextResource location = new ServletContextResource(
				servletContext, configLocation);
		config = new Properties();
		loadProperties(location);
		ConfigUtil.instance(config);
	}

	/**
	 * 加载属性文件
	 * 
	 * @param props
	 * @throws IOException
	 */
	private void loadProperties(Resource location) {
		if (logger.isInfoEnabled()) {
			logger.info("Loading config file from [" + configLocation + "]");
		}
		String filename = location.getFilename();
		InputStream is = null;
		try {
			is = location.getInputStream();
			if (filename != null && filename.endsWith(XML_FILE_EXTENSION)) {
				this.propertiesPersister.loadFromXml(config, is);
			} else {
				if (this.configFileEncoding != null) {
					this.propertiesPersister.load(config,
							new InputStreamReader(is, this.configFileEncoding));
				} else {
					this.propertiesPersister.load(config, is);
				}
			}
		} catch (IOException ex) {
			if (logger.isWarnEnabled()) {
				logger.debug("Could not load config from " + configLocation
						+ ": " + ex.getMessage());
			}
		} finally {
			if (is != null) {
				try {
					is.close();
				} catch (IOException e) {
					logger.debug("Could not close config file "
							+ configLocation + ": " + e.getMessage());
				}
			}
		}
	}

	public String getConfigLocation() {
		return configLocation;
	}

	public void setConfigLocation(String configLocation) {
		this.configLocation = configLocation;
	}

	public String getConfigFileEncoding() {
		return configFileEncoding;
	}

	public void setConfigFileEncoding(String configFileEncoding) {
		this.configFileEncoding = configFileEncoding;
	}

}
